
///////////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2006, Arizona State University
//  All rights reserved.
//  BSD License: http://www.opensource.org/licenses/bsd-license.html
//  Created by: Adam Kubach
//
///////////////////////////////////////////////////////////////////////////////

#include "ConnectionInfo.h"

#include "Usul/Components/Manager.h"
#include "Usul/Factory/RegisterCreator.h"
#include "Usul/Interfaces/IPasswordPrompt.h"
#include "Usul/Scope/Caller.h"
#include "Usul/Strings/Case.h"
#include "Usul/Strings/Format.h"

#include "boost/bind.hpp"

#include <iostream>

using namespace Minerva::Layers::GDAL;


USUL_FACTORY_REGISTER_CREATOR ( ConnectionInfo );

///////////////////////////////////////////////////////////////////////////////
//
//  Constructor.
//
///////////////////////////////////////////////////////////////////////////////

ConnectionInfo::ConnectionInfo() : BaseClass(),
	_host(),
	_database(),
	_user(),
	_password(),
	SERIALIZE_XML_INITIALIZER_LIST
{
  SERIALIZE_XML_ADD_MEMBER ( _host );
  SERIALIZE_XML_ADD_MEMBER ( _database );
  SERIALIZE_XML_ADD_MEMBER ( _user );
	// Don't serialize or deserialize password in clear text.
}


///////////////////////////////////////////////////////////////////////////////
//
//  Destructor.
//
///////////////////////////////////////////////////////////////////////////////

ConnectionInfo::~ConnectionInfo()
{
}


///////////////////////////////////////////////////////////////////////////////
//
//  Get the name.
//
///////////////////////////////////////////////////////////////////////////////

std::string ConnectionInfo::name() const
{
  return this->database() + " on " + this->hostname();
}


///////////////////////////////////////////////////////////////////////////////
//
//  Set the hostname.
//
///////////////////////////////////////////////////////////////////////////////

void ConnectionInfo::hostname( const std::string& host )
{
  _host = host;
}


///////////////////////////////////////////////////////////////////////////////
//
//  Get the hostname.
//
///////////////////////////////////////////////////////////////////////////////

const std::string& ConnectionInfo::hostname() const
{
  return _host;
}


///////////////////////////////////////////////////////////////////////////////
//
//  Set the database.
//
///////////////////////////////////////////////////////////////////////////////

void ConnectionInfo::database( const std::string& db )
{
  _database = db;
}


///////////////////////////////////////////////////////////////////////////////
//
//  Get the database.
//
///////////////////////////////////////////////////////////////////////////////

const std::string& ConnectionInfo::database() const
{
  return _database;
}


///////////////////////////////////////////////////////////////////////////////
//
//  Set the username
//
///////////////////////////////////////////////////////////////////////////////

void ConnectionInfo::username( const std::string& user )
{
  _user = user;
}


///////////////////////////////////////////////////////////////////////////////
//
//  Get the username.
//
///////////////////////////////////////////////////////////////////////////////

const std::string& ConnectionInfo::username() const
{
  return _user;
}


///////////////////////////////////////////////////////////////////////////////
//
//  Set the password.
//
///////////////////////////////////////////////////////////////////////////////

void ConnectionInfo::password( const std::string& pw )
{
  _password = pw;
}


///////////////////////////////////////////////////////////////////////////////
//
//  Get the password.
//
///////////////////////////////////////////////////////////////////////////////

const std::string& ConnectionInfo::password() const
{
  return _password;
}


///////////////////////////////////////////////////////////////////////////////
//
//  Build a connection string.
//
///////////////////////////////////////////////////////////////////////////////

std::string ConnectionInfo::connectionString()
{
	// Check to see if we have a password.
	if ( true == this->password().empty() )
	{
		typedef Usul::Components::Manager PluginManager;
		typedef Usul::Interfaces::IPasswordPrompt IPasswordPrompt;

		IPasswordPrompt::QueryPtr pp ( PluginManager::instance().getInterface ( IPasswordPrompt::IID ) );

		if ( pp.valid() )
		{
			const std::string prompt ( Usul::Strings::format ( "Enter password for ", this->username(), " on ", this->hostname() ) );
			this->password ( pp->promptForPassword ( prompt ) );
		}
	}

  // Connection parameters.
  std::string hostname ( Usul::Strings::format (     "host=", this->hostname() ) );
  std::string database ( Usul::Strings::format (   "dbname=", this->database() ) );
  std::string username ( Usul::Strings::format (     "user=", this->username() ) );
  std::string password ( Usul::Strings::format ( "password=", this->password() ) );
    
  return Usul::Strings::format ( hostname, " ", username, " ", password, " ", database );
}


///////////////////////////////////////////////////////////////////////////////
//
//  Deserialize.
//
///////////////////////////////////////////////////////////////////////////////

void ConnectionInfo::deserialize ( const XmlTree::Node &node )
{
  _dataMemberMap.deserialize ( node );
}
